package cn.skyquant.quant4j.service.boot.model.system;

import cn.skyquant.quant4j.api.system.SystemService;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Service
public class ServiceSystemService implements SystemService {

    @Resource
    private RedisTemplate<String, String> redisTemplate;

    @Resource
    private RedisConnectionFactory redisConnectionFactory;

    private boolean redisConnect = false;

    public boolean isRedisConnect() {
        return redisConnect;
    }

    @PostConstruct
    public void init(){
        String key = getKey();
        try {
            RedisConnection rc = redisConnectionFactory.getConnection();
            redisConnect = !rc.isClosed();
            rc.close();
        }catch (Throwable e){
            return;
        }

        if(key!=null){
            redisTemplate.opsForSet().add(key_name_set,key);
            redisTemplate.opsForHash().putAll(key,fullInfo());
            redisTemplate.expire(key,expireTime, timeUnit);
        }
    }

    @Scheduled(cron = "0 * * * * ? ")
    public void put(){
        if(redisConnect){
            String key = getKey();
            if(key!=null){
                Map map = changedInfo();
                map.forEach((k,v)->redisTemplate.opsForHash().put(key,k,v));
                redisTemplate.expire(key,expireTime, timeUnit);
            }
        }
    }

    @PreDestroy
    public void remove(){
        if(redisConnect){
            String key = getKey();
            if(key!=null){
                redisTemplate.opsForSet().remove(key_name_set,key);
                redisTemplate.delete(key);
            }
        }
    }


    public List<Map> all(){
        Set<String> keySet = redisTemplate.opsForSet().members(key_name_set);
        List<Map> list = new ArrayList<>();
        if(keySet!=null){
            for(String k:keySet){
                Map map = redisTemplate.opsForHash().entries(k);
                if(map.isEmpty()){
                   continue;
                }
                Long expire = redisTemplate.getExpire(k,TimeUnit.MILLISECONDS);
                if(expire!=null && expire>0){
                    map.put("expireTime", System.currentTimeMillis()+expire);
                }
                list.add(map);
            }
        }
        return list;
    }


    public Map get(){
        String key = getKey();
        if(key!=null){
            Map map = redisTemplate.opsForHash().entries(key);
            Long expire = redisTemplate.getExpire(key);
            if(expire!=null && expire>0){
                map.put("expire", expire);
            }
            return map;
        }
        return emptyMap;
    }

    @Override
    public String getName() {
        return "quant4j-service";
    }
}
